﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Text.RegularExpressions;

namespace Lilifei.Custom.Attributes.ORM
{
    /// <summary>
    /// Where条件操作
    /// </summary>
    public class WhereOperateAttribute : Attribute
    {
        public EnumOperationType OperationType { get; set; }

        public string GetValueFormat(string FieldName, string value, ref IDictionary<string, object> values)
        {
            //IDictionary<string, object> values = new Dictionary<string, object>();

            string FomatStr = "";
            switch (OperationType)
            {
                case EnumOperationType.Like:

                    FomatStr = $" {FieldName} like @{FieldName} ";
                    values.Add($"{FieldName}", $"%{value}%");
                    break;

                case EnumOperationType.IdRange:

                    #region 验证数据
                    {
                        if (IsUnValidIdRange(value, FieldName, out string fn, out int StarId, out int EndId))
                        {
                            //非法数据,返回空字符串
                            return string.Empty;
                        }

                        FomatStr = $"  {fn} >=@Start{fn}";
                        values.Add($"Start{fn}", StarId);
                        FomatStr += $"  and {fn} <=@End{fn}";
                        values.Add($"End{fn}", EndId);
                    }
                    #endregion
                    break;


                case EnumOperationType.TimeRange:

                    #region 验证数据
                    {
                        if (IsUnValidDateTimeRange(value, FieldName, out string fn, out DateTime StarTime, out DateTime EndTime))
                        {
                            //非法数据,返回空字符串
                            return string.Empty;
                        }

                        FomatStr = $"  {fn} >=@Start{fn}";
                        values.Add($"Start{fn}", $"{StarTime.ToString("yyyy-MM-dd HH:mm:ss")}");
                        FomatStr += $"  and {fn} <=@End{fn}";
                        values.Add($"End{fn}", $"{EndTime.ToString("yyyy-MM-dd HH:mm:ss")}");
                    }
                    #endregion
                    break;

                case EnumOperationType.DateRange:

                    #region 验证数据
                    {
                        if (IsUnValidDateTimeRange(value, FieldName, out string fn, out DateTime StarTime, out DateTime EndTime))
                        {
                            //非法数据,返回空字符串
                            return string.Empty;
                        }
                        FomatStr = $"  {fn} >=@Start{fn}";
                        values.Add($"Start{fn}", $"{StarTime.ToString("yyyy-MM-dd")}");
                        FomatStr += $"  and {fn} <@End{fn}";
                        values.Add($"End{fn}", $"{EndTime.AddDays(1).ToString("yyyy-MM-dd")}");
                    }
                    #endregion
                    break;




                //case EnumOperationType.IsNotNull:

                //    FomatStr = $" is not null ";
                //    break;

                //case EnumOperationType.IsNull:

                //    FomatStr = $" is null ";
                //    break;

                case EnumOperationType.In:
                    string tick = DateTime.Now.Ticks.ToString();


                    string[] arr = value.Split(new char[] { ',', ';', '，', }, StringSplitOptions.RemoveEmptyEntries);
                    string tempIn = " in ( ";
                    for (int i = 0; i < arr.Length; i++)
                    {
                        tempIn += $"@Param_{tick}_{i},";
                        if (Regex.Match(arr[i], @"^\d+$").Success)
                        {
                            values.Add($"@Param_{tick}_{i}", int.Parse(arr[1]));

                        }
                        else
                        {
                            values.Add($"@Param_{tick}_{i}", arr[i]);
                        }

                    }
                    FomatStr = tempIn.Trim().Trim(',') + ")";

                    break;


                default:
                    break;
            }

            return FomatStr;


        }

        /// <summary>
        /// 是否是非法的Id范围  true:检查未通过; false: 检查通过
        /// </summary>
        /// <returns></returns>
        bool IsUnValidIdRange(string value, string FieldName, out string Fn, out int StarId, out int EndId)
        {
            Fn = string.Empty;
            StarId = -1;
            EndId = -1;

            if (string.IsNullOrEmpty(value))
            {
                //是非法的
                return true;//空字符串,终止
            }


            if (!FieldName.EndsWith("range"))
            {
                //是非法的
                return true;//不是以range结尾,终止
            }

            value = Regex.Replace(value, @"\s*-\s*", "~");
            value = Regex.Replace(value, @"\s*~\s*", "~");

            string[] arrTime = value.Split(new string[] { "~" }, StringSplitOptions.RemoveEmptyEntries);
            if (arrTime.Length != 2)
            {
                //是非法的
                return true;//范围格式不对,终止
            }
            Fn = FieldName.Substring(0, FieldName.Length - 5);
            if (!int.TryParse(arrTime[0], out StarId))
            {
                //是非法的
                return true;//格式不对,终止
            }
            if (!int.TryParse(arrTime[1], out EndId))
            {
                //是非法的
                return true;//格式不对,终止
            }
            int start = Math.Min(StarId, EndId);
            int end = Math.Max(StarId, EndId);
            StarId = start;
            EndId = end;
            return false;
        }



        /// <summary>
        /// 是否是非法的时间范围  true:检查未通过; false: 检查通过
        /// </summary>
        /// <returns></returns>
        bool IsUnValidDateTimeRange(string value, string FieldName, out string Fn, out DateTime StarTime, out DateTime EndTime)
        {
            Fn = string.Empty;
            StarTime = DateTime.Now;
            EndTime = DateTime.Now;

            if (string.IsNullOrEmpty(value))
            {
                //是非法的
                return true;//空字符串,终止
            }


            if (!FieldName.EndsWith("range"))
            {
                //是非法的
                return true;//不是以range结尾,终止
            }


            string[] arrTime = value.Split(new string[] { " - ", " ~ " }, StringSplitOptions.RemoveEmptyEntries);
            if (arrTime.Length != 2)
            {
                //是非法的
                return true;//时间范围格式不对,终止
            }
            Fn = FieldName.Substring(0, FieldName.Length - 5);
            if (!DateTime.TryParse(arrTime[0], out StarTime))
            {
                //是非法的
                return true;//时间格式不对,终止
            }
            if (!DateTime.TryParse(arrTime[1], out EndTime))
            {
                //是非法的
                return true;//时间格式不对,终止
            }

            return false;
        }


        public string GetValueFormat(string value)
        {
            //IDictionary<string, object> values = new Dictionary<string, object>();

            string FomatStr = "";
            switch (OperationType)
            {
                case EnumOperationType.Like:

                    FomatStr = $" like %{value}%";

                    break;

                //case EnumOperationType.IsNotNull:

                //    FomatStr = $" is not null ";
                //    break;

                //case EnumOperationType.IsNull:

                //    FomatStr = $" is null ";
                //    break;

                case EnumOperationType.In:

                    string[] arr = value.Split(new char[] { ',', ';', '，', }, StringSplitOptions.RemoveEmptyEntries);
                    FomatStr = $"'{string.Join("','", arr) }'";
                    break;


                default:
                    break;
            }

            return FomatStr;
        }


    }
}
